package org.wdcode.core.dao.spring.hibernate;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import javax.sql.DataSource;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import org.wdcode.common.log.WdLogs;
import org.wdcode.common.tools.Conversion;
import org.wdcode.common.util.CommonUtil;
import org.wdcode.common.util.SqlUtil;

/**
 * 本类是对org.springframework.orm.hibernate3.support.HibernateDaoSupport(
 * Spring实现HibernateDao)的在封装<br/>
 * 此类不可继承重写，在业务或DAO层直接调用此类方法<br/>
 * 如果封装的方法无法满足需求可用getHibernateTemplate()方法调用原Spring封装的Hibernate Dao方法<br/>
 * @author WD
 * @since JDK6
 * @see org.springframework.orm.hibernate3.support.HibernateDaoSupport
 * @version 1.0 2009-08-31
 */
public class BasicHibernateDao extends HibernateDaoSupport {
	/* 重写方法 */
	/**
	 * 持久化数据，不锁表 更新表中一行数据
	 * @param entity 对象实体
	 */
	public final <E> E update(E entity) {
		return update(entity, null);
	}

	/**
	 * 持久化数据，不锁表 删除表中一行数据
	 * @param entity 对象实体
	 */
	public final <E> E delete(E entity) {
		return delete(entity, null);
	}

	/**
	 * 执行非查询的HQL语言 使用 ? 做参数
	 * @param hql hql语句 不能是查询的
	 * @param value 参数值
	 * @return 返回影响的行数 异常返回-1
	 */
	public final int execute(String hql, List<Object> value) {
		return execute(hql, value.toArray());
	}

	/**
	 * 执行非查询的SQL语言 使用 ? 做参数
	 * @param sql sql语句 不能是查询的
	 * @param value 参数值
	 * @return 返回影响的行数 异常返回-1
	 */
	public final int executeSQL(String sql, List<Object> value) {
		return executeSQL(sql, value.toArray());
	}

	/**
	 * 执行非查询的hbm文件定义名称 使用 ? 做条件
	 * @param name hbm定义语句
	 * @param value 参数值
	 * @return 返回影响的行数 异常返回-1
	 */
	public final int executeByNamed(String name, List<Object> value) {
		return executeByNamed(name, value.toArray());
	}

	/**
	 * 获得持久化对象
	 * @param entityClass 持久化对象的类
	 * @param id 持久化对象的唯一标识(主键)
	 * @return 要获得的持久化对象，如果不存在返回null
	 */
	public final <T> T get(Class<T> entityClass, int id) {
		return get(entityClass, id, null);
	}

	/**
	 * 获得查询的对象实体列表
	 * @param exampleEntity 需要获得的对象，会查询出实体中封装的相等的条件
	 * @return 返回这个对象的列表
	 */
	public final <E> List<E> queryByExample(E exampleEntity) {
		return queryByExample(exampleEntity, -1, -1);
	}

	/**
	 * 根据HQL查询语句查询
	 * @param queryString HQL查询语句 参数为?的语句
	 * @param value 参数列表
	 * @return 返回结果列表
	 */
	public final <E> List<E> query(String queryString, List<Object> value) {
		return query(queryString, value.toArray());
	}

	/**
	 * 根据HQL查询语句查询
	 * @param queryString HQL查询语句 参数为?的语句
	 * @param values 参数数组
	 * @return 返回结果列表
	 */
	public final <E> List<E> query(String queryString, Object... values) {
		return query(queryString, values, -1, -1);
	}

	/**
	 * 根据SQL查询语句查询
	 * @param queryString SQL查询语句 参数为?的语句
	 * @param value 参数值
	 * @return 返回结果列表
	 */
	public final <E> List<E> querySQL(String queryString, Object... value) {
		return querySQL(queryString, value, -1, -1);
	}

	/**
	 * 根据SQL查询语句查询
	 * @param queryString SQL查询语句 参数为?的语句
	 * @param value 参数列表
	 * @return 返回结果列表
	 */
	public final <E> List<E> querySQL(String queryString, List<Object> value) {
		return querySQL(queryString, value.toArray());
	}

	/**
	 * 查询hbm文件定义的查询名称 语句需用 ? 做条件
	 * @param queryName 查询名称
	 * @param value 参数值
	 * @return 返回结果列表
	 */
	public final <E> List<E> queryByNamedQuery(String queryName, List<Object> value) {
		return queryByNamedQuery(queryName, value.toArray());
	}

	/**
	 * 根据DetachedCriteria 查询条件 查询
	 * @param criteria 查询条件
	 * @return 返回结果列表
	 */
	public final <E> List<E> queryByCriteria(DetachedCriteria criteria) {
		return queryByCriteria(criteria, -1, -1);
	}

	/**
	 * 查询entityClass所对应的所有数据
	 * @param entityClass 要查询的实体
	 * @return 返回结果列表
	 */
	public final <E> List<E> queryByAll(Class<E> entityClass) {
		return queryByCriteria(DetachedCriteria.forClass(entityClass));
	}

	/**
	 * 查询entityClass所对应的所有数据
	 * @param entityClass 要查询的实体
	 * @param firstResult 开始查询的条数
	 * @param maxResults 最多查询多少条
	 * @return 返回结果列表
	 */
	public final <E> List<E> queryByAll(Class<E> entityClass, int firstResult, int maxResults) {
		return queryByCriteria(DetachedCriteria.forClass(entityClass), firstResult, maxResults);
	}

	/* 封装方法 */
	/**
	 * 持久化对象，添加操作，此方法会向对应的数据库表中插入一条数据
	 * @param entity 对象实体
	 * @return 返回插入数据的唯一标识(主键) 出现异常返回0
	 */
	public final Integer insert(Object entity) {
		return (Integer) getHibernateTemplate().save(entity);
	}

	/**
	 * 持久化数据，锁表 更新表中一行数据
	 * @param entity 对象实体
	 * @param lockMode 锁表的模式 具体参看 LockMode
	 * @return 是否成功
	 * @see org.hibernate.LockMode
	 */
	public final <E> E update(E entity, LockMode lockMode) {
		getHibernateTemplate().update(entity, lockMode);
		return entity;
	}

	/**
	 * 持久化对象 保存或更新，如果存在就更新，不存在就插入
	 * @param entity 需要持久化的对象
	 * @return 是否成功
	 */
	public final void insertOrUpdate(Object entity) {
		getHibernateTemplate().saveOrUpdate(entity);
	}

	/**
	 * 批量持久化对象 保存或更新，如果存在就更新，不存在就插入
	 * @param entities 需要持久化的对象
	 * @return 列表对象
	 */
	public final <E> List<E> insertOrUpdateAll(List<E> entities) {
		getHibernateTemplate().saveOrUpdateAll(entities);
		return entities;
	}

	/**
	 * 持久化数据，锁表 删除表中一行数据
	 * @param entity 对象实体
	 * @param lockMode 锁表的模式 具体参看LockMode
	 * @return 是否成功
	 * @see org.hibernate.LockMode
	 */
	public final <E> E delete(E entity, LockMode lockMode) {
		getHibernateTemplate().delete(entity, lockMode);
		return entity;
	}

	/**
	 * 持久化数据，删除表中多行数据
	 * @param entities 需要持久话对象的集合
	 * @return 是否成功
	 */
	public final <E> List<E> deleteAll(List<E> entities) {
		getHibernateTemplate().deleteAll(entities);
		return entities;
	}

	/**
	 * 执行非查询的HQL语言 使用 ? 做参数
	 * @param hql hql语句 不能是查询的
	 * @param values 参数值数组
	 * @return 返回影响的行数 异常返回-1
	 */
	public final int execute(String hql, Object... values) {
		return getHibernateTemplate().bulkUpdate(hql, values);
	}

	/**
	 * 获得持久化对象
	 * @param entityClass 持久化对象的类
	 * @param id 持久化对象的唯一标识(主键)
	 * @param lockMode 锁表的模式 具体参看 org.hibernate.LockMode
	 * @return 要获得的持久化对象，异常返回null
	 */
	public final <T> T get(Class<T> entityClass, int id, LockMode lockMode) {
		return id > 0 ? getHibernateTemplate().get(entityClass, id, lockMode) : null;
	}

	/**
	 * 获得查询的对象实体列表
	 * @param exampleEntity 需要获得的对象，会查询出实体中封装的相等的条件
	 * @param firstResult 重第几条开始查询
	 * @param maxResults 一共查回多少条
	 * @return 数据列表 异常返回 Collections.emptyList()
	 */
	@SuppressWarnings("unchecked")
	public <E> List<E> queryByExample(E exampleEntity, int firstResult, int maxResults) {
		return getHibernateTemplate().findByExample(exampleEntity, firstResult, maxResults);
	}

	/**
	 * 查询hbm文件定义的查询名称 语句需用 :name 做条件
	 * @param queryName 查询名称
	 * @param valueBean 参数Bean
	 * @return 返回结果列表
	 */
	@SuppressWarnings("unchecked")
	public final <E> List<E> queryByNamedQueryAndValueBean(String queryName, Object valueBean) {
		return getHibernateTemplate().findByNamedQueryAndValueBean(queryName, valueBean);
	}

	/**
	 * 根据HQL查询语句查询
	 * @param queryString HQL查询语句 参数为:name的语句
	 * @param paramNames 参数名 数组
	 * @param values 参数值 数组
	 * @return 返回结果列表
	 */
	@SuppressWarnings("unchecked")
	public final <E> List<E> queryByNamedParam(String queryString, String[] paramNames, Object... values) {
		return getHibernateTemplate().findByNamedParam(queryString, paramNames, values);
	}

	/**
	 * 根据HQL查询语句查询
	 * @param queryString HQL查询语句 参数为:name的语句
	 * @param valueBean 参数Bean
	 * @return 返回结果列表
	 */
	@SuppressWarnings("unchecked")
	public final <E> List<E> queryByValueBean(String queryString, Object valueBean) {
		return getHibernateTemplate().findByValueBean(queryString, valueBean);
	}

	/**
	 * 查询hbm文件定义的查询名称 语句需用 ? 做条件
	 * @param queryName 查询名称
	 * @param values 参数值 数组
	 * @return 返回结果列表
	 */
	@SuppressWarnings("unchecked")
	public final <E> List<E> queryByNamedQuery(String queryName, Object... values) {
		return getHibernateTemplate().findByNamedQuery(queryName, values);
	}

	/**
	 * 查询hbm文件定义的查询名称 语句需用 :name 做条件
	 * @param queryName 查询名称
	 * @param paramNames 参数名 数组
	 * @param values 参数值 数组
	 * @return 返回结果列表
	 */
	@SuppressWarnings("unchecked")
	public final <E> List<E> queryByNamedQueryAndNamedParam(String queryName, String[] paramNames, Object... values) {
		return getHibernateTemplate().findByNamedQueryAndNamedParam(queryName, paramNames, values);
	}

	/**
	 * 根据DetachedCriteria 查询条件 查询 支持分页
	 * @param criteria 查询条件
	 * @param firstResult 开始查询的条数
	 * @param maxResults 最多查询多少条
	 * @return 返回结果列表
	 */
	@SuppressWarnings("unchecked")
	public final <E> List<E> queryByCriteria(DetachedCriteria criteria, int firstResult, int maxResults) {
		return getHibernateTemplate().findByCriteria(criteria, firstResult, maxResults);
	}

	/**
	 * 查询字段在lo到hi之间的实体
	 * @param entity 查询实体
	 * @param propertyName 字段名
	 * @param lo 开始条件
	 * @param hi 结束条件
	 * @return 返回结果列表
	 */
	public <E> List<E> queryByBetween(E entity, String propertyName, Object lo, Object hi) {
		return queryByBetween(entity, propertyName, lo, hi, -1, -1);
	}

	/**
	 * 查询字段在lo到hi之间的实体
	 * @param entity 查询实体
	 * @param propertyName 字段名
	 * @param lo 开始条件
	 * @param hi 结束条件
	 * @param firstResult 重第几条开始查询
	 * @param maxResults 一共查回多少条
	 * @return 返回结果列表
	 */
	public <E> List<E> queryByBetween(E entity, String propertyName, Object lo, Object hi, int firstResult, int maxResults) {
		return queryByBetween(entity, new String[] { propertyName }, new Object[] { lo }, new Object[] { hi }, firstResult, maxResults);
	}

	/**
	 * 查询字段在lo到hi之间的实体
	 * @param entity 查询实体
	 * @param propertyName 字段名
	 * @param lo 开始条件
	 * @param hi 结束条件
	 * @return 返回结果列表
	 */
	public <E> List<E> queryByBetween(E entity, String[] propertyName, Object[] lo, Object[] hi) {
		return queryByBetween(entity, propertyName, lo, hi, -1, -1);
	}

	/* 实现方法 */
	/**
	 * 执行非查询的HQL语言 使用 :name 做参数
	 * @param hql hql语句 不能是查询的
	 * @param paramNames 参数名 数组
	 * @param values 参数值 数组
	 * @return 返回结果列表 异常返回-1
	 */
	public final int executeByParam(final String hql, final String[] paramNames, final Object... values) {
		// 调用executeWithNativeSession方法 返回影响行数
		return getHibernateTemplate().executeWithNativeSession(new HibernateCallback<Integer>() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Integer doInHibernate(Session session) throws HibernateException {
				// 获得接口
				Query query = session.createQuery(hql);
				// 如果参数不为空
				if (!CommonUtil.isEmpty(values)) {
					// 循环参数列表
					for (int i = 0; i < values.length; i++) {
						// 设置参数
						applyNamedParameterToQuery(query, paramNames[i], values[i]);
					}
				}
				// 返回影响行数
				return query.executeUpdate();
			}
		});
	}

	/**
	 * 执行非查询的SQL语言 使用 ? 做参数
	 * @param sql sql语句 不能是查询的
	 * @param values 参数值数组
	 * @return 返回影响的行数 异常返回-1
	 */
	public final int executeSQL(final String sql, final Object... values) {
		// 调用executeWithNativeSession方法 返回行数
		return getHibernateTemplate().executeWithNativeSession(new HibernateCallback<Integer>() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Integer doInHibernate(Session session) throws HibernateException {
				// 获得Query
				Query query = session.createSQLQuery(sql);
				// 是否有参数
				if (!CommonUtil.isEmpty(values)) {
					// 循环参数
					for (int i = 0; i < values.length; i++) {
						// 设置参数
						query.setParameter(i, values[i]);
					}
				}
				// 执行并返回影响行数
				return query.executeUpdate();
			}
		});
	}

	/**
	 * 执行非查询的HQL语言 使用 :name 做参数
	 * @param sql sql语句 不能是查询的
	 * @param paramNames 参数名 数组
	 * @param values 参数值 数组
	 * @return 返回影响的行数 异常返回-1
	 */
	public final int executeSQLByParam(final String sql, final String[] paramNames, final Object... values) {
		// 调用executeWithNativeSession方法 返回影响行数
		return getHibernateTemplate().executeWithNativeSession(new HibernateCallback<Integer>() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Integer doInHibernate(Session session) throws HibernateException {
				// 获得接口
				Query query = session.createSQLQuery(sql);
				// 如果参数不为空
				if (!CommonUtil.isEmpty(values)) {
					// 循环参数列表
					for (int i = 0; i < values.length; i++) {
						// 设置参数
						applyNamedParameterToQuery(query, paramNames[i], values[i]);
					}
				}
				// 返回影响行数
				return query.executeUpdate();
			}
		});
	}

	/**
	 * 执行非查询的hbm文件定义名称 使用 ? 做条件
	 * @param name hbm定义语句
	 * @param values 参数值数组
	 * @return 返回影响的行数
	 */
	public final int executeByNamed(final String name, final Object... values) {
		// 调用executeWithNativeSession方法
		return getHibernateTemplate().executeWithNativeSession(new HibernateCallback<Integer>() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Integer doInHibernate(Session session) throws HibernateException {
				// 获得Query
				Query query = session.getNamedQuery(name);
				// 是否有参数
				if (!CommonUtil.isEmpty(values)) {
					// 循环参数
					for (int i = 0; i < values.length; i++) {
						// 设置参数
						query.setParameter(i, values[i]);
					}
				}
				// 执行并返回影响行数
				return query.executeUpdate();
			}
		});
	}

	/**
	 * 执行hbm文件定义的非查询语句 语句需用 :name 做条件
	 * @param name 语句名称
	 * @param paramNames 参数名 数组
	 * @param values 参数值 数组
	 * @return 返回结果列表 异常返回-1
	 */
	public final int executeByNamedAndParam(final String name, final String[] paramNames, final Object... values) {
		// 调用executeWithNativeSession方法
		return getHibernateTemplate().executeWithNativeSession(new HibernateCallback<Integer>() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Integer doInHibernate(Session session) throws HibernateException {
				// 获得接口
				Query query = session.getNamedQuery(name);
				// 判断有参数
				if (!CommonUtil.isEmpty(values)) {
					// 循环参数
					for (int i = 0; i < values.length; i++) {
						// 设置参数
						applyNamedParameterToQuery(query, paramNames[i], values[i]);
					}
				}
				// 返回数据
				return query.executeUpdate();
			}
		});
	}

	/**
	 * 获得持久化对象 如果没有查询到对象 返回null
	 * @param entity 对象实体
	 * @return 持久化对象
	 */
	public final <T> T get(T entity) {
		// 获得列表
		List<T> list = queryByExample(entity, 0, 1);
		// 返回数据
		return CommonUtil.isEmpty(list) ? null : list.get(0);
	}

	/**
	 * 根据HQL查询语句查询
	 * @param queryString HQL查询语句 参数为?的语句
	 * @param values 参数数组
	 * @param firstResult 重第几条开始查询
	 * @param maxResults 一共查回多少条
	 * @return 返回结果列表
	 */ 
	@SuppressWarnings("unchecked")
	public final <E> List<E> query(final String queryString, final Object[] values, final int firstResult, final int maxResults) {
		// 调用executeWithNativeSession方法
		return (List<E>) getHibernateTemplate().executeWithNativeSession(new HibernateCallback() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Object doInHibernate(Session session) throws HibernateException {
				// 获得查询对象
				Query queryObject = session.createQuery(queryString);
				// 参数不为空
				if (!CommonUtil.isEmpty(values)) {
					// 循环参数数组
					for (int i = 0; i < values.length; i++) {
						// 给参数赋值
						queryObject.setParameter(i, values[i]);
					}
				}
				// 判断firstResult不小于0
				if (firstResult >= 0) {
					// 设置从firstResult条数据开始查询
					queryObject.setFirstResult(firstResult);
				}
				// 判断maxResults大于0
				if (maxResults > 0) {
					// 设置最多查询maxResults条数据
					queryObject.setMaxResults(maxResults);
				}
				// 返回列表
				return queryObject.list();
			}
		});
	}

	/**
	 * 根据SQL查询语句查询
	 * @param queryString SQL查询语句 参数为?的语句
	 * @param values 参数数组
	 * @param firstResult 重第几条开始查询
	 * @param maxResults 一共查回多少条
	 * @return 返回结果列表
	 */
	@SuppressWarnings("unchecked")
	public final <E> List<E> querySQL(final String queryString, final Object[] values, final int firstResult, final int maxResults) {
		// 调用executeWithNativeSession方法
		return (List<E>) getHibernateTemplate().executeWithNativeSession(new HibernateCallback() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Object doInHibernate(Session session) throws HibernateException {
				// 获得查询数据接口
				Query queryObject = session.createSQLQuery(queryString);
				// 如果参数不为空
				if (!CommonUtil.isEmpty(values)) {
					// 循环参数列表
					for (int i = 0; i < values.length; i++) {
						// 设置参数
						queryObject.setParameter(i, values[i]);
					}
				}
				// 判断firstResult不小于0
				if (firstResult >= 0) {
					// 设置从firstResult条数据开始查询
					queryObject.setFirstResult(firstResult);
				}
				// 判断maxResults大于0
				if (maxResults > 0) {
					// 设置最多查询maxResults条数据
					queryObject.setMaxResults(maxResults);
				}
				// 返回数据列表
				return queryObject.list();
			}
		});
	}

	/**
	 * 根据HQL查询语句查询
	 * @param queryString HQL查询语句 参数为:name的语句
	 * @param paramNames 参数名 数组
	 * @param firstResult 重第几条开始查询
	 * @param maxResults 一共查回多少条
	 * @return 返回结果列表
	 */
	@SuppressWarnings("unchecked")
	public final <E> List<E> queryByNamedParam(final String queryString, final String[] paramNames, final Object[] values, final int firstResult, final int maxResults) {
		// 调用executeWithNativeSession方法
		return (List<E>) getHibernateTemplate().executeWithNativeSession(new HibernateCallback() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Object doInHibernate(Session session) throws HibernateException {
				// 获得查询数据接口
				Query queryObject = session.createQuery(queryString);
				// 如果参数不为空
				if (!CommonUtil.isEmpty(values)) {
					// 循环参数列表
					for (int i = 0; i < values.length; i++) {
						// 设置参数
						applyNamedParameterToQuery(queryObject, paramNames[i], values[i]);
					}
				}
				// 判断firstResult不小于0
				if (firstResult >= 0) {
					// 设置从firstResult条数据开始查询
					queryObject.setFirstResult(firstResult);
				}
				// 判断maxResults大于0
				if (maxResults > 0) {
					// 设置最多查询maxResults条数据
					queryObject.setMaxResults(maxResults);
				}
				// 返回数据列表
				return queryObject.list();
			}
		});
	}

	/**
	 * 根据HQL查询语句查询
	 * @param queryString HQL查询语句 参数为:name的语句
	 * @param valueBean 参数Bean
	 * @param firstResult 重第几条开始查询
	 * @param maxResults 一共查回多少条
	 * @return 返回结果列表
	 */
	@SuppressWarnings("unchecked")
	public final <E> List<E> queryByValueBean(final String queryString, final Object valueBean, final int firstResult, final int maxResults) {
		// 调用executeWithNativeSession方法
		return (List<E>) getHibernateTemplate().executeWithNativeSession(new HibernateCallback() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Object doInHibernate(Session session) throws HibernateException {
				// 获得查询接口
				Query queryObject = session.createQuery(queryString);
				// 设置参数
				queryObject.setProperties(valueBean);

				// 判断firstResult不小于0
				if (firstResult >= 0) {
					// 设置从firstResult条数据开始查询
					queryObject.setFirstResult(firstResult);
				}
				// 判断maxResults大于0
				if (maxResults > 0) {
					// 设置最多查询maxResults条数据
					queryObject.setMaxResults(maxResults);
				}

				// 返回数据列表
				return queryObject.list();
			}
		});
	}

	/**
	 * 查询hbm文件定义的查询名称 语句需用 ? 做条件
	 * @param queryName 查询名称
	 * @param values 参数值 数组
	 * @param firstResult 重第几条开始查询
	 * @param maxResults 一共查回多少条
	 * @return 返回结果列表
	 */
	@SuppressWarnings("unchecked")
	public final <E> List<E> queryByNamedQuery(final String queryName, final Object[] values, final int firstResult, final int maxResults) {
		// 调用executeWithNativeSession方法
		return (List<E>) getHibernateTemplate().executeWithNativeSession(new HibernateCallback() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Object doInHibernate(Session session) throws HibernateException {
				// 获得查询数据接口
				Query queryObject = session.getNamedQuery(queryName);
				// 判断有参数
				if (!CommonUtil.isEmpty(values)) {
					// 循环参数
					for (int i = 0; i < values.length; i++) {
						// 设置参数
						queryObject.setParameter(i, values[i]);
					}
				}
				// 判断firstResult不小于0
				if (firstResult >= 0) {
					// 设置从firstResult条数据开始查询
					queryObject.setFirstResult(firstResult);
				}
				// 判断maxResults大于0
				if (maxResults > 0) {
					// 设置最多查询maxResults条数据
					queryObject.setMaxResults(maxResults);
				}
				// 返回数据
				return queryObject.list();
			}
		});
	}

	/**
	 * 查询hbm文件定义的查询名称 语句需用 :name 做条件
	 * @param queryName 查询名称
	 * @param paramNames 参数名 数组
	 * @param values 参数值 数组
	 * @param firstResult 重第几条开始查询
	 * @param maxResults 一共查回多少条
	 * @return 返回结果列表
	 */
	@SuppressWarnings("unchecked")
	public final <E> List<E> queryByNamedQueryAndNamedParam(final String queryName, final String[] paramNames, final Object[] values, final int firstResult, final int maxResults) {
		// 调用executeWithNativeSession方法
		return (List<E>) getHibernateTemplate().executeWithNativeSession(new HibernateCallback() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Object doInHibernate(Session session) throws HibernateException {
				// 获得查询数据接口
				Query queryObject = session.getNamedQuery(queryName);
				// 判断有参数
				if (!CommonUtil.isEmpty(values)) {
					// 循环参数
					for (int i = 0; i < values.length; i++) {
						// 设置参数
						applyNamedParameterToQuery(queryObject, paramNames[i], values[i]);
					}
				}
				// 判断firstResult不小于0
				if (firstResult >= 0) {
					// 设置从firstResult条数据开始查询
					queryObject.setFirstResult(firstResult);
				}
				// 判断maxResults大于0
				if (maxResults > 0) {
					// 设置最多查询maxResults条数据
					queryObject.setMaxResults(maxResults);
				}
				// 返回数据
				return queryObject.list();
			}
		});
	}

	/**
	 * 查询hbm文件定义的查询名称 HQL需用 :name 做条件
	 * @param queryName 查询名称
	 * @param valueBean 参数Bean
	 * @param firstResult 重第几条开始查询
	 * @param maxResults 一共查回多少条
	 * @return 返回结果列表
	 */
	@SuppressWarnings("unchecked")
	public final <E> List<E> queryByNamedQueryAndValueBean(final String queryName, final Object valueBean, final int firstResult, final int maxResults) {
		// 调用executeWithNativeSession方法
		return (List<E>) getHibernateTemplate().executeWithNativeSession(new HibernateCallback() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Object doInHibernate(Session session) throws HibernateException {
				// 获得查询接口
				Query queryObject = session.getNamedQuery(queryName);
				// 设置参数
				queryObject.setProperties(valueBean);
				// 判断firstResult不小于0
				if (firstResult >= 0) {
					// 设置从firstResult条数据开始查询
					queryObject.setFirstResult(firstResult);
				}
				// 判断maxResults大于0
				if (maxResults > 0) {
					// 设置最多查询maxResults条数据
					queryObject.setMaxResults(maxResults);
				}
				// 返回数据列表
				return queryObject.list();
			}
		});
	}

	/**
	 * 查询字段在lo到hi之间的实体
	 * @param entity 查询实体
	 * @param propertyName 字段名
	 * @param lo 开始条件
	 * @param hi 结束条件
	 * @param firstResult 重第几条开始查询
	 * @param maxResults 一共查回多少条
	 * @return 返回结果列表
	 */
	public final <E> List<E> queryByBetween(E entity, String[] propertyName, Object[] lo, Object[] hi, int firstResult, int maxResults) {
		return queryByCriteria(getDetachedCriteriaForBetween(entity, propertyName, lo, hi), firstResult, maxResults);
	}

	/* 查询总行数 */
	/**
	 * 查询字段在lo到hi之间的实体总数
	 * @param entity 查询实体
	 * @param propertyName 字段名
	 * @param lo 开始条件
	 * @param hi 结束条件
	 * @return 返回结果列表
	 */
	public final int queryByBetweenForCount(Object entity, String[] propertyName, Object[] lo, Object[] hi) {
		return queryByCriteriaForCount(getDetachedCriteriaForBetween(entity, propertyName, lo, hi));
	}

	/**
	 * 获得查询的对象实体总数
	 * @param exampleEntity 需要获得的对象，会查询出实体中封装的相等的条件
	 * @return 对象实体总数 异常返回 0
	 */
	public final int queryByExampleForCount(final Object exampleEntity) {
		// 调用executeWithNativeSession方法
		return getHibernateTemplate().executeWithNativeSession(new HibernateCallback<Integer>() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Integer doInHibernate(Session session) throws HibernateException {
				// 创建查询条件
				Criteria criteria = session.createCriteria(exampleEntity.getClass());
				// 添加实体对象
				criteria.add(Example.create(exampleEntity));
				// 设置获得总行数
				criteria.setProjection(Projections.rowCount());
				// 返回结果
				return Conversion.toInt(criteria.uniqueResult());
			}
		});
	}

	/**
	 * 根据HQL查询语句查询结果数
	 * @param queryString HQL查询语句 参数为?的语句
	 * @param values 参数数组
	 * @return 结果数 异常返回 0
	 */
	public final int queryForCount(final String queryString, final Object... values) {
		// 调用executeWithNativeSession方法
		return getHibernateTemplate().executeWithNativeSession(new HibernateCallback<Integer>() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Integer doInHibernate(Session session) throws HibernateException {
				// 声明分页查询接口
				Query query = session.createQuery(SqlUtil.getCountSQL(queryString));
				// 如果参数不为空
				if (!CommonUtil.isEmpty(values)) {
					// 循环参数列表
					for (int i = 0; i < values.length; i++) {
						// 设置参数
						query.setParameter(i, values[i]);
					}
				}
				// 返回总数
				return Conversion.toInt(query.uniqueResult());
			}
		});
	}

	/**
	 * 根据SQL查询语句查询出总行数
	 * @param queryString SQL查询语句 参数为?的语句
	 * @param value 参数值
	 * @return 结果数 异常返回0
	 */
	public final int querySQLForCount(final String queryString, final Object... values) {
		// 调用executeWithNativeSession方法
		return getHibernateTemplate().executeWithNativeSession(new HibernateCallback<Integer>() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Integer doInHibernate(Session session) throws HibernateException {
				// 声明分页查询接口
				Query queryCount = session.createSQLQuery(SqlUtil.getCountSQL(queryString));
				// 如果参数不为空
				if (!CommonUtil.isEmpty(values)) {
					// 循环参数列表
					for (int i = 0; i < values.length; i++) {
						// 设置参数
						queryCount.setParameter(i, values[i]);
					}
				}
				// 返回结果
				return Conversion.toInt(queryCount.uniqueResult());
			}
		});
	}

	/**
	 * 根据HQL查询语句查询结果数
	 * @param queryString HQL查询语句 参数为:name的语句
	 * @param paramNames 参数名 数组
	 * @param values 参数值 数组
	 * @return 返回结果数 异常返回0
	 */
	public final int queryByNamedParamForCount(final String queryString, final String[] paramNames, final Object... values) {
		// 调用executeWithNativeSession方法
		return getHibernateTemplate().executeWithNativeSession(new HibernateCallback<Integer>() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Integer doInHibernate(Session session) throws HibernateException {
				// 声明分页查询接口
				Query queryCount = session.createQuery(SqlUtil.getCountSQL(queryString));
				// 如果参数不为空
				if (!CommonUtil.isEmpty(values)) {
					// 循环参数列表
					for (int i = 0; i < values.length; i++) {
						// 设置参数
						applyNamedParameterToQuery(queryCount, paramNames[i], values[i]);
					}
				}
				// 返回总数
				return Conversion.toInt(queryCount.uniqueResult());
			}
		});
	}

	/**
	 * 根据HQL查询语句查询 总行数
	 * @param queryString HQL查询语句 参数为:name的语句
	 * @param valueBean 参数Bean
	 * @return 返回结果数 异常返回0
	 */
	public final int queryByValueBeanForCount(final String queryString, final Object valueBean) {
		// 调用executeWithNativeSession方法
		return getHibernateTemplate().executeWithNativeSession(new HibernateCallback<Integer>() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Integer doInHibernate(Session session) throws HibernateException {
				// 获得查询接口
				Query queryCount = session.createQuery(SqlUtil.getCountSQL(queryString));
				// 设置参数
				queryCount.setProperties(valueBean);
				// 返回总数
				return Conversion.toInt(queryCount.uniqueResult());
			}
		});
	}

	/**
	 * 查询hbm文件定义的查询名称 语句需用 ? 做条件
	 * @param queryName 查询名称
	 * @param values 参数值 数组
	 * @return 返回结果数 异常返回0
	 */
	public final int queryByNamedQueryForCount(final String queryName, final Object... values) {
		// 调用executeWithNativeSession方法
		return getHibernateTemplate().executeWithNativeSession(new HibernateCallback<Integer>() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Integer doInHibernate(Session session) throws HibernateException {
				// 声明查询接口
				Query queryCount = session.getNamedQuery(SqlUtil.getCountSQL(session.getNamedQuery(queryName).getQueryString()));
				// 判断有参数
				if (!CommonUtil.isEmpty(values)) {
					// 循环参数
					for (int i = 0; i < values.length; i++) {
						// 设置参数
						queryCount.setParameter(i, values[i]);
					}
				}
				// 返回总数
				return Conversion.toInt(queryCount.uniqueResult());
			}
		});
	}

	/**
	 * 查询hbm文件定义的查询名称 总行数 语句需用 :name 做条件
	 * @param queryName 查询名称
	 * @param paramNames 参数名 数组
	 * @param values 参数值 数组
	 * @return 返回结果数 异常返回0
	 */
	public final int queryByNamedQueryAndNamedParamForCount(final String queryName, final String[] paramNames, final Object... values) {
		// 调用executeWithNativeSession方法
		return getHibernateTemplate().executeWithNativeSession(new HibernateCallback<Integer>() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Integer doInHibernate(Session session) throws HibernateException {
				// 声明查询接口
				Query queryCount = session.getNamedQuery(SqlUtil.getCountSQL(session.getNamedQuery(queryName).getQueryString()));
				// 判断有参数
				if (!CommonUtil.isEmpty(values)) {
					// 循环参数
					for (int i = 0; i < values.length; i++) {
						// 设置参数
						applyNamedParameterToQuery(queryCount, paramNames[i], values[i]);
					}
				}
				// 返回总数
				return Conversion.toInt(queryCount.uniqueResult());
			}
		});
	}

	/**
	 * 查询hbm文件定义的查询名称 总行数 语句需用 :name 做条件
	 * @param queryName 查询名称
	 * @param valueBean 参数Bean
	 * @return 返回结果数 异常返回0
	 */
	public final int queryByNamedQueryAndValueBeanForCount(final String queryName, final Object valueBean) {
		// 调用executeWithNativeSession方法
		return getHibernateTemplate().executeWithNativeSession(new HibernateCallback<Integer>() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Integer doInHibernate(Session session) throws HibernateException {
				// 获得查询接口
				Query queryCount = session.createQuery(SqlUtil.getCountSQL(session.getNamedQuery(queryName).getQueryString()));
				// 设置参数
				queryCount.setProperties(valueBean);
				// 设置总行数
				return Conversion.toInt(queryCount.uniqueResult());
			}
		});
	}

	/**
	 * 根据DetachedCriteria 查询条件 查询总行数
	 * @param criteria 查询条件
	 * @return 返回结果列表 异常返回0
	 */
	public final int queryByCriteriaForCount(final DetachedCriteria criteria) {
		// 调用executeWithNativeSession方法
		return getHibernateTemplate().executeWithNativeSession(new HibernateCallback<Integer>() {
			// 重写HibernateCallback接口的doInHibernate方法
			public Integer doInHibernate(Session session) throws HibernateException {
				// 获得Criteria
				Criteria executableCriteria = criteria.getExecutableCriteria(session);
				// 设置获得行数
				executableCriteria.setProjection(Projections.rowCount());
				// 返回总行数
				return Conversion.toInt(executableCriteria.uniqueResult());
			}
		});
	}

	/**
	 * 获得命名SQL的SQL语句
	 * @param queryName 查询名称
	 * @return SQL
	 */
	public final String getNamedQueryForSQL(final String queryName) {
		// 调用executeWithNativeSession方法
		return getHibernateTemplate().executeWithNativeSession(new HibernateCallback<String>() {
			// 重写HibernateCallback接口的doInHibernate方法
			public String doInHibernate(Session session) throws HibernateException {
				return session.getNamedQuery(queryName).getQueryString();
			}
		});
	}

	/**
	 * 清空整张表
	 * @param tableName 表名
	 */
	public final void truncate(String tableName) {
		executeSQL(SqlUtil.getTruncateSQL(tableName));
	}

	/**
	 * 获得当前Session
	 * @return Session
	 */
	public final Session getCurrentSession() {
		return getSession();
	}

	/**
	 * 获得一个新的Session
	 * @return Session
	 */
	public final Session getNewSession() {
		return SessionFactoryUtils.getNewSession(getSessionFactory());
	}

	/**
	 * 关闭Session
	 * @param session
	 */
	public final void closeSession(Session session) {
		SessionFactoryUtils.closeSession(session);
	}

	/**
	 * 获得一个数据源对象
	 * @return DataSource
	 */
	public final DataSource getDataSource() {
		return SessionFactoryUtils.getDataSource(getSessionFactory());
	}

	/**
	 * 获得JDBC连接
	 * @return Connection 当前的JDBC连接,可直接做JDBC编程
	 * @throws CustomException 获得连接时异常
	 */
	public final Connection getConnection() {
		try {
			return getDataSource().getConnection();
		} catch (SQLException e) {
			WdLogs.error(e);
			return null;
		}
	}

	/**
	 * 给Query设置参数
	 * @param query Query对象
	 * @param name 参数名
	 * @param value 参数值
	 */
	private void applyNamedParameterToQuery(Query query, String name, Object value) {
		// 判断参数类型
		if (value instanceof List<?>) {
			// 参数是List
			query.setParameterList(name, (List<?>) value);
		} else if (value instanceof Object[]) {
			// 参数是Object[]
			query.setParameterList(name, (Object[]) value);
		} else {
			// 其它
			query.setParameter(name, value);
		}
	}

	/**
	 * queryByBetween使用 返回DetachedCriteria
	 * @param entity 查询实体
	 * @param propertyName 字段名
	 * @param lo 开始条件
	 * @param hi 结束条件
	 * @return DetachedCriteria
	 */
	private DetachedCriteria getDetachedCriteriaForBetween(Object entity, String[] propertyName, Object[] lo, Object[] hi) {
		// 获得criteria
		DetachedCriteria criteria = DetachedCriteria.forClass(entity.getClass());
		// 添加实体条件
		criteria.add(Example.create(entity));
		// 循环添加范围条件
		for (int i = 0; i < propertyName.length; i++) {
			// 添加条件
			criteria.add(Restrictions.between(propertyName[i], lo[i], hi[i]));
		}
		// 返回DetachedCriteria
		return criteria;
	}
}
